import s94Mjs from "s94-js";

/**获取字符串宽度
 * @param {string} str 字符串
 * @param {string} [size] 字体大小，例如：12px、1rem
 * @param {string} [family] 字体
 * @returns {number} 宽度，单位px
 */
export function string_width(str, size, family){
    const tempEl = document.createElement('span');
    if (size) tempEl.style.fontSize = size;
    if (family) tempEl.style.fontFamily = family;
    tempEl.style.position = 'absolute';
    tempEl.style.visibility = 'hidden';
    tempEl.innerText = str;

    // 将元素添加到文档中
    document.body.appendChild(tempEl);

    // 获取宽度
    const width = tempEl.offsetWidth;

    // 移除临时元素
    document.body.removeChild(tempEl);

    return width;
}

/**
 * 获取一组字符串的最大宽度
 * @param {string[]} list 字符串数组
 * @param {string} [size] 字体大小，例如：12px、1rem
 * @param {string} [family] 字体
 * @returns {number} 宽度，单位px
 */
export function string_width_max(list, size, family){
    const tempEl = document.createElement('span');
    if (size) tempEl.style.fontSize = size;
    if (family) tempEl.style.fontFamily = family;
    tempEl.style.position = 'absolute';
    tempEl.style.visibility = 'hidden';
    // 将元素添加到文档中
    document.body.appendChild(tempEl);

    const res = list.reduce((max, str)=>{
        tempEl.innerText = str;
        // 获取宽度
        const width = tempEl.offsetWidth;
        max =  Math.max(width, max);
        return max;
    }, 0)

    // 移除临时元素
    document.body.removeChild(tempEl);

    return res;
}

/**获取媒体(视频、音频)时长，
 * @param {string|Blob} file 媒体文件，可以为地址
 * @param {boolean} [is_video] 是否为视频
 * @returns {Promise<unknown>} 获取的时长(秒)
 */
export function media_duration(file, is_video){
    let dom = document.createElement(is_video?'video':'audio');
    return new Promise((resolve, reject)=>{
        dom.src = typeof file === 'string' ? file : URL.createObjectURL(file);

        dom.addEventListener('loadedmetadata', ()=>{
            resolve(dom.duration);
            dom = null;
        }, {once:true});
        dom.addEventListener('error', (e)=>{
            reject(new Error('媒体文件加载失败'));
            dom = null;
        }, {once:true})
    })
}

/**模拟vue模板语法，解析html
 * @param {string} html 模板内容
 * @param {Object} data 参数
 * @returns {string} 解析后的内容
 */
export function vue_template(html, data){
    let outer_dom = document.createElement('div');
    outer_dom.innerHTML = html;
    outer_dom = loop(outer_dom, data);
    return outer_dom.innerText;

    function exp(body,param_name,param_value){
        try {
            return Function.apply(null, param_name.concat(['return ' + body])).apply(null, param_value);
        } catch (e) {
            let data = {};
            param_name.forEach(function(k,i){data[k] = param_value[i]});
            console.warn('template表达式('+body+')执行出错：'+e.message, data);
        }
    }
    function loop(dom, param){
        let param_name = Object.keys(param);
        let param_value = Object.values(param);
        let children = [];
        dom.childNodes.forEach(function(v){children.push(v)});
        for (let i = 0; i < children.length; i++) {
            let row=children[i];
            switch (row.nodeName){
                case '#text':{
                    row.textContent = row.textContent.replace(/\{\{(.+?)\}\}/g,function(m,v){
                        return exp(v,param_name,param_value);
                    })
                }break;
                default:{
                    let exp_if = row.getAttribute('v-if');
                    let exp_for = row.getAttribute('v-for');
                    row.removeAttribute('v-if');
                    row.removeAttribute('v-for');
                    if (exp_if){
                        if (!exp(exp_if,param_name,param_value)) {
                            dom.removeChild(row); break;
                        }
                    }
                    let is_template = row.nodeName=='TEMPLATE';
                    let old_row = row;
                    if (is_template){
                        row = document.createElement('div');
                        row.innerHTML = old_row.innerHTML;
                    }
                    let is_for, ms, list;
                    is_for = exp_for && (ms=exp_for.match(/^(\S+) in (.+)$/)) && (list=exp(ms[2],param_name,param_value));
                    if (is_for){
                        let arr = ms[1].split(',');
                        let param_add = {};
                        for (let k in list) {
                            param_add[arr[0]] = list[k];
                            if (arr.length>1) param_add[arr[1]] = k;
                            let copy_row = loop(row.cloneNode(true), Object.assign({},param,param_add));
                            if (is_template){
                                while (copy_row.childNodes.length){
                                    dom.insertBefore(copy_row.childNodes[0],old_row);
                                }
                            }else {
                                dom.insertBefore(copy_row,old_row);
                            }
                        }
                        dom.removeChild(old_row);
                    }else {
                        if (is_template){
                            loop(row,param);
                            while (row.childNodes.length){
                                dom.insertBefore(row.childNodes[0],old_row);
                            }
                            dom.removeChild(old_row);
                        }else {
                            loop(row, param);
                        }
                    }
                }
            }
        }
        return dom;
    }
}
